我的意思是为什么std::make_tuple
存在?我知道在某些情况下,该函数会减少您必须键入的字符数,因为您可以避免使用模板参数.但这是唯一的原因吗?std::tuple
当其他类模板没有这样的功能时,该功能存在的特殊之处是什么?是否只是因为你可能std::tuple
在这种情况下更频繁地使用?
以下是两个std::make_tuple
减少字符数量的示例:
// Avoiding template parameters in definition of variable. // Consider that template parameters can be very long sometimes. std::tuplet(0, 0.0); // without std::make_tuple auto t = std::make_tuple(0, 0.0); // with std::make_tuple // Avoiding template parameters at construction. f(std::tuple (0, 0.0)); // without std::make_tuple f(std::make_tuple(0, 0.0)); // with std::make_tuple
但是,如上所述,对于许多其他类模板,您没有这样的函数.
因为你不能对构造函数使用参数推导.你需要明确写 std::tuple
.
它使得创建元组并将其一次性传递给另一个函数变得更加方便.
takes_tuple(make_tuple(i,d))
VS takes_tuple(tuple
.
当类型i
或d
更改时,更少的地方可以更改,特别是如果旧类型和新类型之间可能存在转换.
如果有可能写std::tuple(i,d);
,make_*
将(可能)是多余的.
(不要在这里问为什么.也许出于类似的原因,为什么语法A a();
不会调用默认的构造函数.有一些痛苦的c ++语法特性.)
更新说明: 正如Daniel正确地注意到的那样,c ++ 17将得到增强,因此模板参数推导将适用于构造函数,并且这种委托将变得过时.
我们可以找到我们需要的原因make_tuple
以及提案N3602中的各种其他make_*实用程序:构造函数的模板参数推导(表示强调我的):
本文提出将函数的模板参数推导扩展到模板类的构造函数.描述问题和解决方案的最清晰方式是一些例子.
假设我们已经定义了以下内容.
vectorvi1 = { 0, 1, 1, 2, 3, 5, 8 }; vector vi2; template class Foo() { public: Foo(Func f) : func(f) {} void operator()(int i) { os << "Calling with " << i << endl; f(i); } private: Func func; }; 目前,如果我们想要实例化模板类,我们需要指定模板参数或使用"make_*"包装器,利用函数的模板参数推导,或者完全解决:
pairp(2, 4.5); auto t = make_tuple(4, 3, 2.5); copy_n(vi1, 3, back_inserter(vi2)); // Virtually impossible to pass a lambda to a template class' constructor for_each(vi.begin(), vi.end(), Foo??>([&](int i) { ...}));
请注意,该提案正在通过EWG第60期进行跟踪.